| Contents > Welcome > Getting Started |
|
Software developers have
asked many questions about Microsoft's .NET Framework since it was first
introduced. Some of the confusion stems from the fact that the .NET Framework
isn't just one thing. The .NET Framework is an initiative begun by Microsoft,
to facilitate the development of web-based applications, through the use of
standardized protocols such as HTTP, and SOAP. The .NET Framework class library
and common language runtime are software development environments, created to
support these new applications and web services. The .NET initiative consists
of several standards and technologies, which together will fundamentally change
the way software is developed on the Windows platform:
As a new software
development environment, the .NET Framework has already produced many positive
effects. For starters, the .NET Framework implements rules for deploying
assemblies. The rules define a specific location where developers should deploy
assemblies that will be shared by multiple applications. It allows different
versions of the same assembly to be deployed side-by-side, so that applications
are not broken when a different application installs a newer version of the
same shared component.
The CIL produced by the
compiler can be analyzed for type safety before being executed, preventing
potentially dangerous type coercions that can be exploited by malicious code.
Another benefit comes from
the automatic memory management provided by the CLR. The .NET Framework's
garbage collected memory manager tracks all memory allocations, and recovers
memory when it determines that memory is no longer referenced.
A full discussion of the
.NET Framework is found on Microsoft's
MSDN website. The Borland Developer
Network also features technical articles, and registered customers will be
able to access updates on Borland's .NET tools as they become available.
The .NET Framework is a
radical departure from the old ways of developing software for Windows, but
some of the ideas it brings to the table aren't new. In fact the idea for
compiling to a neutral intermediate language goes back all the way to the late
1950's. In 1958, an article by Melvin E. Conway appeared in the Journal for the
Association for Computing Machinery, titled "Proposal For An
UNCOL" (Universal Computer-Oriented Language). Conway's paper
describes an intermediate language, which he called SML (simple machine
language). The article even mentions tagging the intermediate code with
metadata, which would serve as hints for the final translation to native
machine instructions.
One of the motivations
behind the UNCOL was to free programmers from having to worry about the
hardware-specific intricacies of each platform. To bring the lofty goal of
portability to fruition required much more than just the definition of an
intermediate language. Not only must compilers produce intermediate code, but
also an environment must be created in which to execute that code. The virtual
execution system (VES) provides the services required to make platform
neutrality a viable goal.
The road towards a universal
language and execution environment has been long. Today, virtual execution
environments such as the Java Virtual Machine (JVM) and Microsoft's Common
Language Runtime give programmers some of the long sought after portability. Complex graphical user interfaces have proven to be a troublesome aspect of
developing a truly portable application, but even so, intermediate languages,
runtime compilation, and virtual execution systems have greatly broadened
developers' deployment opportunities.
It is Borland's intention to
evolve the Delphi language and its runtime libraries to fully support the new
execution model of Microsoft's CLR. Further, it is Borland's intention to so in a way that makes migration to the new execution model as seamless as
possible for Delphi developers. The Delphi language will be more than a CLR consumer.
It will be a CLR extender, giving developers a tremendous advantage by
allowing them to leverage their existing code, fully exploit the CLR, and
extend the .NET Framework Class Library.
Runtime compilation is the
key to portability in a virtual execution system. It is the mechanism that
allows developers to target such disparate hardware platforms as Intel's
Pentium 4 and ARM processors, with a single code base. The Delphi for .NET
Preview compiler already produces CLS-compliant intermediate code, although the
compiler is not yet feature-complete at this stage.
The CLR is not an
interpreted execution environment. The runtime, or "Just in Time"
(JIT) compiler always produces native machine instructions prior to execution.
The .NET Framework SDK includes a utility called ngen, which can be used
to compile CIL to native instructions and then cache the compiled code to disk.
There are still advantages to using runtime compilation however. The JIT
compiler has far greater knowledge of the end-user's execution environment;
therefore it can take advantage of processor specific optimizations that
utilities like ngen aren't aware of.
The JIT compiler performs
many of the same optimizations done by the current Delphi compiler, including
The JIT also performs
automatic function inlining, which can greatly improve performance of nested
function calls.
While JIT compilation
broadens horizons, no claims such as "Write once, run anywhere" have
been made with regard to the .NET Framework. Non-graphical code is fully
portable between platforms that provide a CLI-compliant runtime environment. It
is not reasonable, however, to expect a user interface to be 100% portable from
a desktop running at a resolution of 1600x1200 pixels, to a handheld device
capable of displaying only 240x320 pixels. Certainly, developers should plan on
making significant design considerations when targeting both the desktop, and
handheld devices.
Language compilers that
target the CLR are said to produce managed applications. The term managed
is used because the CLR completely takes over the process of loading,
verifying, compiling, optimizing, and executing the CIL produced by the
compiler. The CLR features a generational, garbage collected memory manager,
which tracks memory usage and frees memory when it is no longer referenced. The
.NET Framework Class Library exposes many more services provided by the CLR,
such as type reflection, a unified exception model, and rich debugging support.
Code that is compiled to native machine instructions (in the traditional sense)
is called unmanaged code, since it is not loaded or executed by the CLR.
It is expected that much of
your existing Delphi code will compile and run in the CLR, but keep in mind
that not all of the programming practices allowed in the native Win32
environment are sanctioned by the CLR. There is a distinction between managed
and unmanaged code, and, within the CLR, there is a distinction between safe
and unsafe code.
Prior to compilation, the
JIT compiler performs static analysis of CIL code. This verification process
ensures the code is type-safe:
Microsoft also includes a
command line utility with the .NET Framework SDK, called peverify. This
utility is used to confirm that a managed code module contains safe IL code.
It is important to realize
that the JIT compiler does not compile an application in its entirety when it
is first loaded. JIT compilation truly means "just in time", and it
might not happen until a method is actually called. This can lead to situations
where code will compile and pass the analysis of peverify (and the JIT
compiler), but that code will not run when deployed, because the JIT compiler
cannot find the method.
As long as you are compiling
and deploying to the same version of the runtime, all is well. However, as new
versions of the .NET Framework appear, you might begin to see this problem. For
example, it can happen if you build against a newer version of the .NET
Framework, and your code is run against a prior version.
Type-safe verification is
possible because .NET Framework assemblies are self-describing. The metadata
emitted by the compiler fully describes the types implemented and referenced by
the assembly. CIL code that can be verified said to be safe code. Code that
cannot be verified is unsafe. Not all managed code is safe code, and the .NET
Framework allows system administrators to set their local policies to determine
whether or not the CLR is allowed to execute unsafe code.
In order to produce safe
code, certain features of the Delphi language had to either be removed, or
severely restricted. In particular, operations on absolute memory addresses are
being deprecated. Unsafe types such as PChar and variant records are currently
the subjects of ongoing research to determine how they will be supported in
future revisions of the Delphi compiler.
The CLR provides automatic
memory management, so the memory allocation functions GetMem(), FreeMem(),
and ReallocMem() are deprecated. The constructor-destructor mechanisms
of Delphi are being rewritten to use the dispose pattern, so that your
existing classes can gain the advantage of automatic memory management, and you
can write new classes with the same Create/Destroy constructors and destructors
that you are already familiar with.
The .NET Framework's bridge
to unmanaged code, called P/Invoke (for Platform Invoke), is supported in
Delphi for .NET. You can call unmanaged code (e.g. the Win32 API), using the DllImport
custom attribute. The ability to use unmanaged COM servers is a feature of the
.NET Framework, and is also supported in Delphi for .NET.
Beyond platform neutrality,
the CLR offers another powerful capability: true integration of different
programming languages. The CLR is designed from the ground up to allow both
language interoperability (in the COM sense), and transparent usage of types
developed in different programming languages. The CLR does not know what
language was used to develop a .NET component or application. As long as the
compiler complies with the CLS, all of the interoperability and integration
features of the CLR are automatically available.
Delphi is going to be a
first-class citizen in the .NET Framework. You can use Delphi to write managed
applications using the .NET Framework Class Library directly. You can also
extend those classes with Delphi for .NET using the traditional mechanism of
inheritance. Furthermore, since Delphi for .NET will be fully CLS compliant,
developers writing in other languages can use and extend components written in
Delphi. And if that's not enough, remember that this bridge is a two-way street -
Delphi developers can extend components written in other .NET languages such as
Visual Basic and C#.
The basic unit of deployment
in the .NET Framework is called an assembly. An assembly can consist of
IL code, data such as images and resource strings, or both. An assembly can be
a single file (e.g. a dynamic link library, or executable), or it can be made
up of several files. Each assembly contains a piece of metadata called the manifest.
The manifest describes all the files that make up the assembly, as well as all
the files the assembly depends on.
Because they contain both
code and data, .NET assemblies are analogous to Delphi packages. Indeed, in
Delphi for .NET, package syntax will produce an assembly.
| Top | Contents | Copyrights | Borland Developer Network | Borland Home |